home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <string.h>
- #include <ctype.h>
- #include <assert.h>
-
- /**** init_globals(fp, names, types, ...)
- **
- ** public domain by Raymond Gardner Sept. 1991
- **
- ** fp is a FILE * to the (already fopen'ed) file containing
- ** initialization data
- ** names is a space-separated list of names of globals (as they
- ** are to appear in the data file)
- ** types is a list of datatype characters, corresponding to names
- ** i for a pointer to integer
- ** s for a pointer to string (already allocated char array)
- ** p for a pointer to pointer to char (space will be malloc'd)
- ** (NOTE: no whitespace allowed in types !!)
- ** followed by var arg list of pointers to variables to init
- */
-
- #define LNSZ 256
-
- int init_globals(FILE *fp, char *names, char *types, ...)
- {
- char ln[LNSZ];
- char *p;
- va_list arglist;
- char *namep, *typep, name[40], *e;
- void *argp;
- int k;
-
- while ( fgets(ln, LNSZ, fp) ) { /* read init file */
- while ( isspace(ln[0]) ) /* drop leading whitespace */
- memmove(ln, ln+1, strlen(ln));
- if ( ln[0] == 0 ) /* skip if blank line */
- continue;
- p = strchr(ln, '='); /* find equal sign */
- if ( p == NULL ) /* error if none */
- return -1; /* or continue; */
- while ( p > ln && isspace(p[-1]) ) { /* remove whitespace */
- memmove(p-1, p, strlen(p-1)); /* before = sign */
- --p;
- }
- *p++ = 0; /* plug EOS over = sign */
- while ( isspace(p[0]) ) /* remove leading space on */
- memmove(p, p+1, strlen(p)); /* init string */
- k = strlen(p) - 1; /* init string length */
- if ( k < 1 )
- return -1;
-
- if ( p[k] != '\n' ) /* if '\n' is missing, input */
- return -1; /* exceeded buffer; error return */
- p[k] = 0; /* plug EOS over newline */
-
- va_start(arglist, types); /* setup for arglist search */
-
- namep = names; /* init ptr to var names */
- typep = types; /* init ptr to var types */
- while ( *namep == ' ' ) /* skip blanks before namelist */
- ++namep;
- while ( *typep ) { /* while any typelist items left...*/
-
- argp = (void *)va_arg(arglist, void *); /* get var arg */
-
- k = strcspn(namep, " "); /* length of namelist entry */
- memmove(name, namep, k); /* put into name hold area */
- name[k] = 0; /* terminate it */
- if ( strcmp(name, ln) != 0 ) { /* if it doesn't match... */
- namep += k; /* get next name */
- while ( *namep == ' ' )
- ++namep;
- ++typep; /* get next type */
- } else { /* else name is found... */
- if ( *typep == 'i' ) { /* if it's an int, init it */
- *(int *)argp = atoi(p);
- } else if ( *typep == 's' || *typep == 'p' ) {
- if ( *p == '"' ) { /* is string in quotes? */
- ++p; /* skip leading quote, and */
- e = strchr(p, '"'); /* look for trailing quote */
- if ( e ) /* terminate string if found */
- *e = 0;
- }
- if ( *typep == 'p' ) { /* if it's a char *ptr */
- e = malloc(strlen(p) + 1); /* get space */
- if ( e == 0 ) { /* error if no space */
- return -1; /* call va_end(arglist); first? */
- }
- *(char **)argp = e;
- strcpy(*(char **)argp, p); /* copy in string */
- } else /* must be char array */
- strcpy(argp, p); /* copy in string */
- } else {
- return -1; /* bad type */
- }
- break; /* break search; get next line */
- }
- }
- va_end(arglist);
- }
- return 0;
- }
- #ifdef TEST
-
- int foo;
- char bar[80];
- int baz;
- char *quux;
-
- int main(int argc, char **argv)
- {
- FILE *fp;
- int k;
-
- if ( argc < 2 ) {
- fprintf(stderr, "missing arg\n");
- exit(1);
- }
-
- fp = fopen(argv[1], "r");
- assert(fp);
- k = init_globals(fp, "foo bar baz quux", "isip",
- &foo, bar, &baz, &quux);
- printf("k: %d\n", k);
- printf("foo: %d\nbar: <%s>\nbaz: %d\nquux: <%s>\n",
- foo, bar, baz, quux);
- fclose(fp);
-
- return 0;
- }
- #endif
- /* test data file:
- foo=123
- bar = "a test"
- baz = 456
- quux= what is this
- */
-